Help with creating sides
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.
- Atreides
- Posts: 1092
- Joined: March 30th, 2019, 10:38 pm
- Location: On the 2nd story of the centre village of Merwuerdigliebe turning the lights on and off
Re: Help with creating sides
Programming rule #1: There is always an easier way and you will always discover it... afterwards.Mr_Moist wrote: ↑November 10th, 2023, 12:44 pmThank you so much! I didn't know there was such an easy way for that!Pentarctagon wrote: ↑November 4th, 2023, 12:51 amSee https://wiki.wesnoth.org/DirectActionsW ... recruit.5D and the next couple tags following it.Mr_Moist wrote: ↑November 4th, 2023, 12:24 am But this is the first scenario, what can I do for the list to change within the scenario at specific events? I want the player to be able to encounter someone on a specific location and then being able to recruit more different units. I should probably make a new thread for that right?
Re: Help with creating sides
Hello again,Spannerbag wrote: ↑November 4th, 2023, 1:33 pm Hiya,
Edit: missed off last bit of post
Just to clarify,Mr_Moist wrote: ↑November 3rd, 2023, 2:29 pm Hi,
...While I know that "testvar" is just a placeholder for a name of a variable, I want to make sure I understand the "first" thing after the variable name. I would assume it is the value of the variable? If this is right, could I also write "$testvar" instead of the value? I ask this, because I want to have two events were something will be added to the variable, but I can't be sure which one would fire first if it even fired at all.
I will fix the errors about the spawning and then look into the log and also change the variable things.
Also thank you for the good wishes.
{VARIABLE.. is a core macro that comes with the game, the definition is:
So it's just the sameCode: Select all
#define VARIABLE VAR VALUE # Macro to initialize a variable. Strictly a syntatic shortcut. [set_variable] name={VAR} value={VALUE} [/set_variable] #enddef
[set_variable]
as you used, I'm just lazy
{VARIABLE testvar "first"}
Sets the value of the variable namedtestvar
to the string "first".
So the value oftestvar
(i.e.$testvar
) is now "first", though it could be anything you want; -99, 4.77 or "W1Bbl3".
{DEBUG_MSG (_"before: testvar=$testvar")}
This is just a lazy way of displaying the value oftestvar
before.png
{VARIABLE testvar "$testvar|second"} # This appends "second" to $testvar's value
This setstestvar
to "the present value" with the string "second" immediately bolted on.
{DEBUG_MSG (_"after: testvar=$testvar")}
after.png
Hope this helps/makes sense!
Cheers!
-- Spannerbag
first of all, thanks for the fast answer and sorry for the long wait for my answer. Now another thanks for the explaining, but I do have another question:
I want to add something to the recruiting list after a moveto event, I should be able to do that with the set_extra_recruit, right? But is that also possible with multiple events where something will be added to the recruiting list?
But anyway, even if that works, I still need the event to fire, and I think that doesn't happen: It should spawn a unit that then talks to my leader, afterwards you are supposed to be able to recruit more different units. But I can't seem to make it work, here is my code:
Code: Select all
[event]
name=moveto
[filter]
x=29
y=46
[/filter]
[unit]
type=Elvish Ranger
side=1
x=28
y=46
id=Legolas
gender=male
name=Legolas
unrenamable=yes
upkeep=loyal
[/unit]
[message]
speaker=Legolas
message=_"Ich will euch in dem Kampf gegen diese Monster begleiten, ich werde eine große Hilfe sein!"
[/message]
[message]
speaker=Friedhelm
message=_"Großartig! Wir können jede Hilfe brauchen, ihr könnt uns bestimmt einige von euren Tricks zeigen?"
[/message]
[message]
speaker=Legolas
message=_"Aber natürlich!"
[/message]
[set_extra_recruit]
extra_recruit=Elvish Fighter,Elvish Scout,Elvish Shaman
[/set_extra_recruit]
[/event]
[event]
name=moveto
[filter]
x=20
y=49
[/filter]
[unit]
type=Skeleton Archer
side=1
x=21
y=49
id=Arthur
name=Arthur
unrenamable=yes
upkeep=loyal
[/unit]
[message]
speaker=Arthur
message=_"Diese Orks hatten mich getötet und ich will mich an ihnen rächen. Ich möchte euch helfen!"
[/message]
[message]
speaker=Friedhelm
message=_"Eine gruselige, aber willkomene Überraschung, natürlich könnt ihr uns beitreten!"
[/message]
[message]
speaker=Arthur
message=_"Vielen Dank, ich habe euch auch die Möglichkeit mitgebracht, andere Seelen, die elbenfalls eine offene Rechnung mit den Orks haben, ausbilden zu können."
[/message]
[set_extra_recruit]
extra_recruit=Ghost,Skeleton,Walking Corpse,Dark Adept
[/set_extra_recruit]
[/event]
- Atreides
- Posts: 1092
- Joined: March 30th, 2019, 10:38 pm
- Location: On the 2nd story of the centre village of Merwuerdigliebe turning the lights on and off
Re: Help with creating sides
Check out mainline campaign a tale of two brothers the chase scenario where you catch muff toras has exactly that where a iron mauler joins you and adds heavy inf to recruits. (I just played this so it came to mind )
- lhybrideur
- Posts: 379
- Joined: July 9th, 2019, 1:46 pm
Re: Help with creating sides
I think the problem here is that [set_extra_recruit] is missing the unit filter to say who is able to recruit the extra units.
so
Code: Select all
[set_extra_recruit]
extra_recruit=Elvish Fighter,Elvish Scout,Elvish Shaman
[/set_extra_recruit]
Code: Select all
[set_extra_recruit]
id=id_of_your_leader
extra_recruit=Elvish Fighter,Elvish Scout,Elvish Shaman
[/set_extra_recruit]
- Spannerbag
- Posts: 562
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: Help with creating sides
Hi,
To narrow down the options you'll at least need
If you want only the leader(s) of side 1 to cause this event to fire then use:
Little hint on code optimisation (unless things have changed since I read about this): place the most restrictive filter condition first so the remaining filter conditions have fewer units to test (as I understand it after each filter component a list of units is stored and these are tested by the next filter component and so on).
Here the most restrictive condition is x,y= as this limits the filter to 1 unit at x,y=29,46 so subsequent tests can be in any order.
If side 1 has only one leader (or you want only one specific leader amongst 2+) to fire the event then you can use:
Just a thought
Just to make it clear that a leader has two recruit lists;
Cheers!
-- Spannerbag
I think this will fire when any unit happens to move to x,y=29,46.Mr_Moist wrote: ↑November 14th, 2023, 4:27 pmCode: Select all
[event] name=moveto [filter] x=29 y=46 [/filter]
To narrow down the options you'll at least need
side=1
(assuming side 1 is the player's side) to restrict the unit(s) triggering this event to player units.If you want only the leader(s) of side 1 to cause this event to fire then use:
Code: Select all
[event]
name=moveto
[filter]
x,y=29,46
side=1
canrecruit=yes
[/filter]
Here the most restrictive condition is x,y= as this limits the filter to 1 unit at x,y=29,46 so subsequent tests can be in any order.
If side 1 has only one leader (or you want only one specific leader amongst 2+) to fire the event then you can use:
Code: Select all
[event]
name=moveto
[filter]
x,y=29,46
side=1
id=leader_id
[/filter]
If you want to draw attention to this unit you can addMr_Moist wrote: ↑November 14th, 2023, 4:27 pmCode: Select all
[unit] type=Elvish Ranger side=1 x=28 y=46 id=Legolas gender=male name=Legolas unrenamable=yes upkeep=loyal [/unit]
animate=yes
and the unit will appear using the recruit/recall animation.Just a thought
lhybrideur has already explained that you're missing which leader(s) can recruit these unit(s).Mr_Moist wrote: ↑November 14th, 2023, 4:27 pmCode: Select all
[set_extra_recruit] extra_recruit=Elvish Fighter,Elvish Scout,Elvish Shaman [/set_extra_recruit]
Just to make it clear that a leader has two recruit lists;
- The side recruit list specified by
recruit=
and modified byallow_recruit
anddisallow_recruit
(all leaders on this side are able to recruit these units) - The leader's "personal" recruit list specified by
allow_extra_recruit
anddisallow_extra_recruit
You're welcome, hope the above is useful
Cheers!
-- Spannerbag
Re: Help with creating sides
WML keys are not preserved as how they are in your source file, so x,y,side=29,46,1 is equal to side,x,y=1,29,46. In order to have difference the conditions need to be in separate tags, even [and] might work. Because tags are ordered - if there are multiple [and], then code can ask them by index. Some representations of WML sort keys alphabetically.Spannerbag wrote: ↑November 15th, 2023, 11:04 pm Little hint on code optimisation (unless things have changed since I read about this): place the most restrictive filter condition first so the remaining filter conditions have fewer units to test (as I understand it after each filter component a list of units is stored and these are tested by the next filter component and so on).
Here the most restrictive condition is x,y= as this limits the filter to 1 unit at x,y=29,46 so subsequent tests can be in any order.
If side 1 has only one leader (or you want only one specific leader amongst 2+) to fire the event then you can use:Code: Select all
[event] name=moveto [filter] x,y=29,46 side=1 id=leader_id [/filter]
The code that uses keys of WML tag might take them in specific order, for example you can check how [set_variable] is implemented in Lua. Internal code supporting filter might do similar. It is just not affected by whether you put side or location or something else first.
And there is the general idea of premature optimizations.
- Spannerbag
- Posts: 562
- Joined: December 18th, 2016, 6:14 pm
- Location: Yes
Re: Help with creating sides
Hi,
The section does begin by saying:
Of course it may also be that I've completely misunderstood what the wiki is saying, in which case I'd appreciate some clarification for my little brain
Cheers!
-- Spannerbag
Fair enough, but I got the idea from https://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter#Ordering_and_writing which has I think changed since when I last read it in-depth (years ago).Ravana wrote: ↑November 16th, 2023, 12:00 amWML keys are not preserved as how they are in your source file, so x,y,side=29,46,1 is equal to side,x,y=1,29,46. In order to have difference the conditions need to be in separate tags, even [and] might work. Because tags are ordered - if there are multiple [and], then code can ask them by index. Some representations of WML sort keys alphabetically.Spannerbag wrote: ↑November 15th, 2023, 11:04 pm Little hint on code optimisation (unless things have changed since I read about this): place the most restrictive filter condition first so the remaining filter conditions have fewer units to test (as I understand it after each filter component a list of units is stored and these are tested by the next filter component and so on).
Here the most restrictive condition is x,y= as this limits the filter to 1 unit at x,y=29,46 so subsequent tests can be in any order.
If side 1 has only one leader (or you want only one specific leader amongst 2+) to fire the event then you can use:Code: Select all
[event] name=moveto [filter] x,y=29,46 side=1 id=leader_id [/filter]
The code that uses keys of WML tag might take them in specific order, for example you can check how [set_variable] is implemented in Lua. Internal code supporting filter might do similar. It is just not affected by whether you put side or location or something else first.
And there is the general idea of premature optimizations.
The section does begin by saying:
Which is new to me, but further down it says this, which is the bit I remember:It’s very important to note that evaluation order of top level conditions (those not embedded in and/or/not tags) is unspecified, which means your code shouldn’t rely on it. On the contrary, and/or/not tags are always executed last, in the order they are written.
I would find it helpful if the wiki explained either when tests can be ordered to improve performance (i.e. the example above should include [filter_wml] if omitting that negates the performance boost) or removes this performance note entirely if it's no longer (ever was?) relevant.⇒ Performance. Most of the time, performance is not an issue. But it can be if you have a lot of units and use [filter_wml]. More generally, it’s good programming practice to execute the more restrictive test first. Consider this example:
[filter]
race=orc
x,y=16,22
[/filter]
The first condition will be evaluated on all units. But the second one will be evaluated on all orcs. If instead we write:
[filter]
x,y=16,22
race=orc
[/filter]
obviously, the second condition will be evaluated once at most, and filtering will be faster. (Strictly speaking, I should have wrapped the second condition in an and tag to force evaluation order). Remember too that logical operators (and, or, not) are not mandatory, but are allowed. So one can use them for clarity's sake, or to force an evaluation order. It’s particularly important when using or tags.
Of course it may also be that I've completely misunderstood what the wiki is saying, in which case I'd appreciate some clarification for my little brain
Cheers!
-- Spannerbag
Re: Help with creating sides
The red sentence is meant in theory. Next sentence says that without [and] it does not actually change what happens. To be fair, to further optimize you could even put x and y in separate [and] based on which coordinate is expected to have less units.
If you do not have performance issues then do not focus on filter evaluation order. Avoid unneeded [filter_wml] but even if you need to use it, its ok unless you see real issues during game.
If you do not have performance issues then do not focus on filter evaluation order. Avoid unneeded [filter_wml] but even if you need to use it, its ok unless you see real issues during game.
Re: Help with creating sides
I agree that the example code should be rewritten. But it just needs anSpannerbag wrote: ↑November 16th, 2023, 12:04 pm I would find it helpful if the wiki explained either when tests can be ordered to improve performance (i.e. the example above should include [filter_wml] if omitting that negates the performance boost) or removes this performance note entirely if it's no longer (ever was?) relevant.
[and]
tag, not [filter_wml]
.It seems like the author was trying to explain the concept of improving performance while at the same time illustrating a possible pitfall, but the result is rather confusing.
Re: Help with creating sides
Hello everyone, thanks for all your help and advice, but I have now found the problem: the moveto event event was outside of the scenario tag.
But now I have another question : I want to have two events that give you extra recruit, but if one fires and then the other one fires, the first extra recruit gets overwritten by the second one.
Currently it looks like this:
But now I have another question : I want to have two events that give you extra recruit, but if one fires and then the other one fires, the first extra recruit gets overwritten by the second one.
Currently it looks like this:
Code: Select all
[event]
name=moveto
[filter]
side=1
x=29
y=46
[/filter]
[unit]
type=Elvish Ranger
side=1
x=28
y=46
id=Legolas
gender=male
name=Legolas
unrenamable=yes
upkeep=loyal
animation=yes
[/unit]
[message]
speaker=Legolas
message=_"Ich will euch in dem Kampf gegen diese Monster begleiten, ich werde eine große Hilfe sein!"
[/message]
[message]
speaker=Friedhelm
message=_"Großartig! Wir können jede Hilfe brauchen, ihr könnt uns bestimmt einige von euren Tricks zeigen?"
[/message]
[message]
speaker=Legolas
message=_"Aber natürlich!"
[/message]
[set_extra_recruit]
id=Friedhelm
extra_recruit=Elvish Fighter,Elvish Scout,Elvish Shaman
[/set_extra_recruit]
[/event]
[event]
name=moveto
[filter]
side=1
x=20
y=49
[/filter]
[unit]
type=Skeleton Archer
side=1
x=21
y=49
id=Arthur
name=Arthur
unrenamable=yes
upkeep=loyal
animation=yes
[/unit]
[message]
speaker=Arthur
message=_"Diese Orks hatten mich getötet und ich will mich an ihnen rächen. Ich möchte euch helfen!"
[/message]
[message]
speaker=Friedhelm
message=_"Eine gruselige, aber willkomene Überraschung, natürlich könnt ihr uns beitreten!"
[/message]
[message]
speaker=Arthur
message=_"Vielen Dank, ich habe euch auch die Möglichkeit mitgebracht, andere Seelen, die elbenfalls eine offene Rechnung mit den Orks haben, ausbilden zu können."
[/message]
[set_extra_recruit]
id=Friedhelm
extra_recruit=Ghost,Skeleton,Walking Corpse,Dark Adept
[/set_extra_recruit]
[/event]
[/scenario]
Re: Help with creating sides
I just had the idea that I could use extra recruit for one event and recruit for the other event. Would that work, and if yes would there be another way and if not... why?
Re: Help with creating sides
I just tried the idea I previously had and it works! Thank you to everyone for helping me to get this far!
- lhybrideur
- Posts: 379
- Joined: July 9th, 2019, 1:46 pm
Re: Help with creating sides
The solution to your problem is that you should use allow_extra_recruit instead of set_extra_recruit. Their name explain the reason why.
- Celtic_Minstrel
- Developer
- Posts: 2290
- Joined: August 3rd, 2012, 11:26 pm
- Location: Canada
- Contact:
Re: Help with creating sides
I'm not completely certain, but I believe that this discussion of optimizing filters is almost entirely obsolete. (It's also confusingly phrased, which doesn't really help.) My understanding is that the game sees that the filter contains the x,y keys before it evaluates anything else and automatically just checks to see if the unit on that space matches the remainder of the filter. It also has similar handling for a few other keys that can drastically narrow the search area.Spannerbag wrote: ↑November 16th, 2023, 12:04 pm Fair enough, but I got the idea from https://wiki.wesnoth.org/FilterWML/Examples_-_How_to_use_Filter#Ordering_and_writing which has I think changed since when I last read it in-depth (years ago).
The section does begin by saying:Which is new to me, but further down it says this, which is the bit I remember:It’s very important to note that evaluation order of top level conditions (those not embedded in and/or/not tags) is unspecified, which means your code shouldn’t rely on it. On the contrary, and/or/not tags are always executed last, in the order they are written.
I would find it helpful if the wiki explained either when tests can be ordered to improve performance (i.e. the example above should include [filter_wml] if omitting that negates the performance boost) or removes this performance note entirely if it's no longer (ever was?) relevant.⇒ Performance. Most of the time, performance is not an issue. But it can be if you have a lot of units and use [filter_wml]. More generally, it’s good programming practice to execute the more restrictive test first. Consider this example:
[filter]
race=orc
x,y=16,22
[/filter]
The first condition will be evaluated on all units. But the second one will be evaluated on all orcs. If instead we write:
[filter]
x,y=16,22
race=orc
[/filter]
obviously, the second condition will be evaluated once at most, and filtering will be faster. (Strictly speaking, I should have wrapped the second condition in an and tag to force evaluation order). Remember too that logical operators (and, or, not) are not mandatory, but are allowed. So one can use them for clarity's sake, or to force an evaluation order. It’s particularly important when using or tags.
Of course it may also be that I've completely misunderstood what the wiki is saying, in which case I'd appreciate some clarification for my little brain