Connection failed:An existing connection was forcibly closed by the remote host
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.
- LordAwsomeness
- Posts: 203
- Joined: August 12th, 2013, 2:20 pm
- Location: U.S.A.
Connection failed:An existing connection was forcibly closed by the remote host
Hi all! so I was just wondering what is the deal with this bug here. I was attempting to load a scenario from a separate but co-dependent addon, but it keeps getting kicked from the server
- Been playing Wesnoth since 2004 and the 1.0.x versions.
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Pentarctagon
- Project Manager
- Posts: 5533
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Connection failed:An existing connection was forcibly closed by the remote host
Can you provide the information listed here?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
- LordAwsomeness
- Posts: 203
- Joined: August 12th, 2013, 2:20 pm
- Location: U.S.A.
Re: Connection failed:An existing connection was forcibly closed by the remote host
Yes!
Operating system: windows 10 home edition
Build:
Spoiler:
- Start wesnoth with my addon LA_RPG_ERA version 0.3.5a installed.
- Go to multiplayer and choose the main server or the secondary server (i tried it on both).
- login and create a game with the map 'Arena Survival' (it also does it with my maps 'Maze' and 'Evolve')
- after creating the game it will take you to the game lobby for only a couple of seconds, and then the error will appear. If you need access to the version of my addon that is causing this issue please let me know and ill create a google drive link for you.
Code: Select all
20200311 18:38:15 warning network: Failed to connect to 2a02:2178:1000:202::134: No connection could be made because the target machine actively refused it
20200311 18:38:18 warning network: Failed to connect to 2a02:2178:1000:202::134: No connection could be made because the target machine actively refused it
- Been playing Wesnoth since 2004 and the 1.0.x versions.
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
Re: Connection failed:An existing connection was forcibly closed by the remote host
The mp server has a maximum size for the scenarios you can play on it, (size here is the same as savefile size, not the size of the addon on your disk). Since we talked about problems with your addons size in other forum topics already, it is very likely that this is the same problem: Your addon uses macros in a horribly inefficient way.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
Re: Connection failed:An existing connection was forcibly closed by the remote host
Could the error message be improved then?
Re: Connection failed:An existing connection was forcibly closed by the remote host
I'm not sure as i don't know that code very well, maybe if you file a bugrport loonycyborg might look at it.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
- LordAwsomeness
- Posts: 203
- Joined: August 12th, 2013, 2:20 pm
- Location: U.S.A.
Re: Connection failed:An existing connection was forcibly closed by the remote host
I'm so sorry, I'm not trying to sound like a broken record but how would I shrink my files? Like we're talking about how macros are expanded by preprocessors correct? So even if I didn't use nested macros and I still coded it all out as is it would still come to the same conclusion as the files would still end up being expanded to the same size in the preprocessors' eyes. So what solution is there? And does incorporating image files affect this as well, or just the .cfg files that the preprocessor has to unfold?gfgtdf wrote: ↑March 12th, 2020, 2:52 am The mp server has a maximum size for the scenarios you can play on it, (size here is the same as savefile size, not the size of the addon on your disk). Since we talked about problems with your addons size in other forum topics already, it is very likely that this is the same problem: Your addon uses macros in a horribly inefficient way.
EDIT: would using UNDEF also help to some extent? I keep seeing in my error logs that I didn't explicitly #UNDEF a macro.
- Been playing Wesnoth since 2004 and the 1.0.x versions.
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Pentarctagon
- Project Manager
- Posts: 5533
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Connection failed:An existing connection was forcibly closed by the remote host
Image files do not affect the WML cache entry size - it only contains text.
As for #undef, probably not, though it's not good practice to redefine a macro definition without the #undef.
As for #undef, probably not, though it's not good practice to redefine a macro definition without the #undef.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
- LordAwsomeness
- Posts: 203
- Joined: August 12th, 2013, 2:20 pm
- Location: U.S.A.
Re: Connection failed:An existing connection was forcibly closed by the remote host
why is that?Pentarctagon wrote: ↑March 12th, 2020, 4:19 pm As for #undef, probably not, though it's not good practice to redefine a macro definition without the #undef.
And where/when would I use undefine as to avoid creating bugs for my addon?
- Been playing Wesnoth since 2004 and the 1.0.x versions.
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Pentarctagon
- Project Manager
- Posts: 5533
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Connection failed:An existing connection was forcibly closed by the remote host
It isn't good for code readability to have the same macro do different things depending only on where in the file, or in which file, it's used. The #undef, while not required, explicitly marks the point at which the macro's current definition is removed, which means any time the macro is used after that point it's referring to something else.LordAwsomeness wrote: ↑March 12th, 2020, 4:30 pmwhy is that?Pentarctagon wrote: ↑March 12th, 2020, 4:19 pm As for #undef, probably not, though it's not good practice to redefine a macro definition without the #undef.
And where/when would I use undefine as to avoid creating bugs for my addon?
And for your add-on's size, the answer is pretty much the same as before - you need to re-implement your largest and most frequently used macros as lua functions and-or somehow re-implement your macros using fewer lines of code. You have an exceptionally rare problem, and there isn't any easy fix.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: Connection failed:An existing connection was forcibly closed by the remote host
#undef is generally not needed. But when you get warning, it often means you load some code more times than it is needed.
Re: Connection failed:An existing connection was forcibly closed by the remote host
You have to write your code differntly, there is to no general patch to appl toa all situations, you have to do 'programming'. I don't know how your code exactly looks like, but lets take an example of a 'bad' code: Lets assume you want to give a unit hitpoints for money dependent on what race it hasLordAwsomeness wrote: ↑March 12th, 2020, 3:51 pm I'm so sorry, I'm not trying to sound like a broken record but how would I shrink my files? Like we're talking about how macros are expanded by preprocessors correct? So even if I didn't use nested macros and I still coded it all out as is it would still come to the same conclusion as the files would still end up being expanded to the same size in the preprocessors' eyes. So what solution is there?
Code: Select all
#define OPTION_HITPOINTS RACE COST HP
[option]
[show_if]
[has_unit]
x,y=$x1,$y1
race={RACE}
[/has_unit]
[/show_if]
label="buy hitpopoints"
[command]
[modify_unit]
[fllter]
x,y=$x1,$y1
[/fllter]
hitpoints="$($this_unit.hitpoints + {HP})"
[/modify_unit]
[modify_side]
side=$current_side
gold= "$($side.gold + {COST})"
[/modify_side]
[message]
mesage="better poor than sick"
[/message]
[/command]
[/option]
[option]
[shot_if]
[has_unit]
x,y=$x1,$y1
race={RACE}
[/has_unit]
[/shot_if]
label="Sell hitpopoints"
[command]
[modify_unit]
[fllter]
x,y=$x1,$y1
[/fllter]
hitpoints="$($this_unit.hitpoints - {HP})"
[/modify_unit]
[modify_side]
side=$current_side
gold= "$($side.gold - {COST})"
[/modify_side]
[message]
mesage="i'm dying lol"
[/message]
[/command]
[/option]
#endedf
...
later:
[message]
{OPTION_HITPOINTS Elves 10 10}
{OPTION_HITPOINTS Drakes 2 10}
{OPTION_HITPOINTS Humans 4 10}
{OPTION_HITPOINTS Trolls 5 10}
{OPTION_HITPOINTS Orks 2 10}
{OPTION_HITPOINTS Toads 5 10}
{OPTION_HITPOINTS Trees 9 10}
{OPTION_HITPOINTS UsbAdaptors 0 10}
{OPTION_HITPOINTS Juices 7 10}
{OPTION_HITPOINTS DrunkPeople -6 10}
[/message]
Code: Select all
#define RACE_DATA RACE COST HP
[race]
id={RACE}
cost={COST}
hp={HP}
[/race]
#enddef
[set_variables]
name="race_data"
[literal]
{RACE_DATA Elves 10 10}
{RACE_DATA Drakes 2 10}
{RACE_DATA Humans 4 10}
{RACE_DATA Trolls 5 10}
{RACE_DATA Orks 2 10}
{RACE_DATA Toads 5 10}
{RACE_DATA Trees 9 10}
{RACE_DATA UsbAdaptors 0 10}
{RACE_DATA Juices 7 10}
{RACE_DATA DrunkPeople -6 10}
[/literal]
[/set_variables]
[foreach]
array=race_data.race
[do]
[if]
[variable]
name="$this_item.id"
equals="$unit.race"
[/variable]
[then]
[message]
[option]
label="buy hitpopoints"
[command]
[modify_unit]
[fllter]
x,y=$x1,$y1
[/fllter]
hitpoints="$($this_unit.hitpoints + $this_item.hp)"
[/modify_unit]
[modify_side]
side=$current_side
gold= "$($side.gold + $this_item.cost)"
[/modify_side]
[message]
mesage="better poort than sick"
[/message]
[/command]
[/option]
[option]
label="Sell hitpopoints"
[command]
[modify_unit]
[fllter]
x,y=$x1,$y1
[/fllter]
hitpoints="$($this_unit.hitpoints - $this_item.hp)"
[/modify_unit]
[modify_side]
side=$current_side
gold= "$($side.gold - $this_item.cost)"
[/modify_side]
[message]
mesage="im dying lol"
[/message]
[/command]
[/option]
[/message]
[/then]
[/do]
[/foreach]
## important: don't forget to clear the variable afterwards
[CLEAR_VARIABLE race_data]
Now the code that you have have to optmize is probably a little more example then my toy example, but the idea stays the same: replace big macros with wml calculation . If its gets more complicated you will probably have to use [insert_tag].
And lastly that i wanted to say that if i would have to write this code for my addon, i'd probably not use either of those codes i write above and write the whole thing in lua instead. Which will allow me to make it even faster and smaller.
No this warning usually means that you are parsing a file more than once, meaning you have a file that defines macros, lets call it a.cfg and multiple other files doLordAwsomeness wrote: ↑March 12th, 2020, 3:51 pm EDIT: would using UNDEF also help to some extent? I keep seeing in my error logs that I didn't explicitly #UNDEF a macro.
{a.cfg}
.This is true, but coding it all out makes it obvious where your problem is: If you have a macro that uses other macros that again uses other macros etc its sometimes not easy so see where the big part of your code that causes this problem comes from.LordAwsomeness wrote: ↑March 12th, 2020, 3:51 pm So even if I didn't use nested macros and I still coded it all out as is it would still come to the same conclusion as the files would still end up being expanded to the same size in the preprocessors' eyes.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
- LordAwsomeness
- Posts: 203
- Joined: August 12th, 2013, 2:20 pm
- Location: U.S.A.
Re: Connection failed:An existing connection was forcibly closed by the remote host
Thank you so much for giving me literal examples with an explanation! This is by far the easiest way for me to learn so I genuinely appreciate it!gfgtdf wrote: ↑March 12th, 2020, 6:00 pm You have to write your code differntly, there is to no general patch to appl toa all situations, you have to do 'programming'. I don't know how your code exactly looks like, but lets take an example of a 'bad' code: Lets assume you want to give a unit hitpoints for money dependent on what race it has
Now this code get expanded to 500 lines of code since the macro OPTION_HITPOINTS is 50 lines long and is used 10 times (okay this is not really problem yet, but its just an exampel and for now we assume that 500 line would be a lot), to optmize of we have to replace the redundent code (the content of the OPTION_HITPOINTS macro is mostly repetition we we replace repetition my macro by wml code that does the same thing, in our example we coudl do the followingCode: Select all
#define OPTION_HITPOINTS RACE COST HP [option] [show_if] [has_unit] x,y=$x1,$y1 race={RACE} [/has_unit] [/show_if] label="buy hitpopoints" [command] [modify_unit] [fllter] x,y=$x1,$y1 [/fllter] hitpoints="$($this_unit.hitpoints + {HP})" [/modify_unit] [modify_side] side=$current_side gold= "$($side.gold + {COST})" [/modify_side] [message] mesage="better poor than sick" [/message] [/command] [/option] [option] [shot_if] [has_unit] x,y=$x1,$y1 race={RACE} [/has_unit] [/shot_if] label="Sell hitpopoints" [command] [modify_unit] [fllter] x,y=$x1,$y1 [/fllter] hitpoints="$($this_unit.hitpoints - {HP})" [/modify_unit] [modify_side] side=$current_side gold= "$($side.gold - {COST})" [/modify_side] [message] mesage="i'm dying lol" [/message] [/command] [/option] #endedf ... later: [message] {OPTION_HITPOINTS Elves 10 10} {OPTION_HITPOINTS Drakes 2 10} {OPTION_HITPOINTS Humans 4 10} {OPTION_HITPOINTS Trolls 5 10} {OPTION_HITPOINTS Orks 2 10} {OPTION_HITPOINTS Toads 5 10} {OPTION_HITPOINTS Trees 9 10} {OPTION_HITPOINTS UsbAdaptors 0 10} {OPTION_HITPOINTS Juices 7 10} {OPTION_HITPOINTS DrunkPeople -6 10} [/message]
This new code used a smaller macro (RACE_DATA) which is 5 lines long 10 times so its total size will be the number of line of the code below which is 50 lines plus the 50 lines from using the race_data macro 5 times, which is 100 lines, one fifth of the original code!Code: Select all
#define RACE_DATA RACE COST HP [race] id={RACE} cost={COST} hp={HP} [/race] #enddef [set_variables] name="race_data" [literal] {RACE_DATA Elves 10 10} {RACE_DATA Drakes 2 10} {RACE_DATA Humans 4 10} {RACE_DATA Trolls 5 10} {RACE_DATA Orks 2 10} {RACE_DATA Toads 5 10} {RACE_DATA Trees 9 10} {RACE_DATA UsbAdaptors 0 10} {RACE_DATA Juices 7 10} {RACE_DATA DrunkPeople -6 10} [/literal] [/set_variables] [foreach] array=race_data.race [do] [if] [variable] name="$this_item.id" equals="$unit.race" [/variable] [then] [message] [option] label="buy hitpopoints" [command] [modify_unit] [fllter] x,y=$x1,$y1 [/fllter] hitpoints="$($this_unit.hitpoints + $this_item.hp)" [/modify_unit] [modify_side] side=$current_side gold= "$($side.gold + $this_item.cost)" [/modify_side] [message] mesage="better poort than sick" [/message] [/command] [/option] [option] label="Sell hitpopoints" [command] [modify_unit] [fllter] x,y=$x1,$y1 [/fllter] hitpoints="$($this_unit.hitpoints - $this_item.hp)" [/modify_unit] [modify_side] side=$current_side gold= "$($side.gold - $this_item.cost)" [/modify_side] [message] mesage="im dying lol" [/message] [/command] [/option] [/message] [/then] [/do] [/foreach] ## important: don't forget to clear the variable afterwards [CLEAR_VARIABLE race_data]
Now the code that you have have to optmize is probably a little more example then my toy example, but the idea stays the same: replace big macros with wml calculation . If its gets more complicated you will probably have to use [insert_tag].
And lastly that i wanted to say that if i would have to write this code for my addon, i'd probably not use either of those codes i write above and write the whole thing in lua instead. Which will allow me to make it even faster and smaller.
Im trying to study lua and it doesn't make too much sense to be completely honest. how would I make code that is similar to what you did above in lua?
Also how would I make the code above have multiple variables that need to be met rather than just race? say it needs the this_unit's race, level, and something else like another variable that isn't directly tied to the individual unit itself?
would it simply be:
Code: Select all
[foreach]
array=race_data.race
[do]
[if]
[variable]
name="$this_item.id"
equals="$unit.race"
[/variable]
[variable]
name="$unit.level"
equals="2"
[/variable]
[variable]
name="$dog_has_been_walked"
equals="yes"
[/variable]
[then]
[message]
EDIT: also would using [set_variables] be better than using:
Code: Select all
{VARIABLE la_hero[$side_number].magic.runic.aura1.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.aura1.cooldown.max 6}
{VARIABLE la_hero[$side_number].magic.runic.aura1.cost 8}
{VARIABLE la_hero[$side_number].magic.runic.aura2.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.aura2.cooldown.max 6}
{VARIABLE la_hero[$side_number].magic.runic.aura2.cost 8}
{VARIABLE la_hero[$side_number].magic.runic.aura3.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.aura3.cooldown.max 6}
{VARIABLE la_hero[$side_number].magic.runic.aura3.cost 8}
{VARIABLE la_hero[$side_number].magic.runic.aura4.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.aura4.cooldown.max 6}
{VARIABLE la_hero[$side_number].magic.runic.aura4.cost 8}
{VARIABLE la_hero[$side_number].magic.runic.forge1.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.forge1.cooldown.max 4}
{VARIABLE la_hero[$side_number].magic.runic.forge1.cost 5}
{VARIABLE la_hero[$side_number].magic.runic.forge2.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.forge2.cooldown.max 4}
{VARIABLE la_hero[$side_number].magic.runic.forge2.cost 5}
{VARIABLE la_hero[$side_number].magic.runic.forge3.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.forge3.cooldown.max 4}
{VARIABLE la_hero[$side_number].magic.runic.forge3.cost 5}
{VARIABLE la_hero[$side_number].magic.runic.forge4.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.forge4.cooldown.max 4}
{VARIABLE la_hero[$side_number].magic.runic.forge4.cost 5}
{VARIABLE la_hero[$side_number].magic.runic.thornmail.cost 4}
{VARIABLE la_hero[$side_number].magic.runic.thornmail.cooldown 0}
{VARIABLE la_hero[$side_number].magic.runic.thornmail.cooldown.max 4}
- Been playing Wesnoth since 2004 and the 1.0.x versions.
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
- Creator of Undead Invasion MP Scenario Pack.
- Creator of Valeria MP Adventure
- Creator of LA_RPG ERA
Re: Connection failed:An existing connection was forcibly closed by the remote host
I did some playing around with
That guided me to LA_MENU_SUBLEVEL*, I believe that has chance to be quite large.
UNIT_SPAWN_GUARD_RETURN is responsible for 65*18 lines.
LA_RAND_ANIMAL_LOCATIONS is example of repeating code without macro.
LA_TROOP_DIFFICULTY is easily simplified.
LA_TOWER_SET gives ~110*4*4 lines.
LA_REQUIREMENT_EVENT goes more deeply than I currently look for, but seems likely to be large.
LA_BEAST_KILLS_EVENT can be one event only.
wmlscope -c
That guided me to LA_MENU_SUBLEVEL*, I believe that has chance to be quite large.
UNIT_SPAWN_GUARD_RETURN is responsible for 65*18 lines.
LA_RAND_ANIMAL_LOCATIONS is example of repeating code without macro.
LA_TROOP_DIFFICULTY is easily simplified.
LA_TOWER_SET gives ~110*4*4 lines.
LA_REQUIREMENT_EVENT goes more deeply than I currently look for, but seems likely to be large.
LA_BEAST_KILLS_EVENT can be one event only.
Code: Select all
"utils/dungeon/spawning.cfg", line 341: global macro LA_MENU_SUBLEVEL is used in 1 files:
utils/dungeon/spawning.cfg: 83, 85, 87, 108, 110, 112, 114, 145, 175, 177, 179, 181, 183, 204, 206, 208, 210, 212, 214, 236, 237, 238
"scenarios/maze.cfg", line 463: more than one definition of LA_REQUIREMENT_EVENT is visible here ("scenarios/survival.cfg", line 316; "utils/dungeon/events.cfg", line 644).
- Pentarctagon
- Project Manager
- Posts: 5533
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Connection failed:An existing connection was forcibly closed by the remote host
You might shave a fraction of a fraction of a second off load times, but that's the absolute most you would get out of it.LordAwsomeness wrote: ↑March 12th, 2020, 6:15 pm EDIT: also would using [set_variables] be better than using:I know they both have the same end result but I just want to know if its better to do it one way or another (like does [set_variables] have less of a negative impact than {VARIABLE}?)Code: Select all
{VARIABLE la_hero[$side_number].magic.runic.aura1.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.aura1.cooldown.max 6} {VARIABLE la_hero[$side_number].magic.runic.aura1.cost 8} {VARIABLE la_hero[$side_number].magic.runic.aura2.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.aura2.cooldown.max 6} {VARIABLE la_hero[$side_number].magic.runic.aura2.cost 8} {VARIABLE la_hero[$side_number].magic.runic.aura3.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.aura3.cooldown.max 6} {VARIABLE la_hero[$side_number].magic.runic.aura3.cost 8} {VARIABLE la_hero[$side_number].magic.runic.aura4.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.aura4.cooldown.max 6} {VARIABLE la_hero[$side_number].magic.runic.aura4.cost 8} {VARIABLE la_hero[$side_number].magic.runic.forge1.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.forge1.cooldown.max 4} {VARIABLE la_hero[$side_number].magic.runic.forge1.cost 5} {VARIABLE la_hero[$side_number].magic.runic.forge2.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.forge2.cooldown.max 4} {VARIABLE la_hero[$side_number].magic.runic.forge2.cost 5} {VARIABLE la_hero[$side_number].magic.runic.forge3.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.forge3.cooldown.max 4} {VARIABLE la_hero[$side_number].magic.runic.forge3.cost 5} {VARIABLE la_hero[$side_number].magic.runic.forge4.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.forge4.cooldown.max 4} {VARIABLE la_hero[$side_number].magic.runic.forge4.cost 5} {VARIABLE la_hero[$side_number].magic.runic.thornmail.cost 4} {VARIABLE la_hero[$side_number].magic.runic.thornmail.cooldown 0} {VARIABLE la_hero[$side_number].magic.runic.thornmail.cooldown.max 4}
edit-
Also, moved to the WML Workshop, given the change in topic and that this isn't a bug in Wesnoth.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code