Questions about [event] name=time over

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
demario
Posts: 20
Joined: July 3rd, 2019, 1:05 pm

Questions about [event] name=time over

Post by demario »

I am playing around with turn limits in players vs player games (PvP).
It appears that when the turn limit is reached or that time over event is fired, a nice dialog is showing giving a computer generated estimation on the status of the game. Like in the attached picture.

I have several questions on the code this WML is triggering:
  • what are the formula used for that estimation? Can it be modified?
  • is it possible to fire the calculations at will (ie before turn limit is reached)?
  • is it possible to retrieve the result from calculation in WML variables?
  • after the dialogs show, both players are still shown "you have been defeated dialog". Is it possible to decide the winner based on the calculations?
Much thanks for the guidance!
Attachments
Side 2 has the advantage
Side 2 has the advantage
BFW-1.14.timeover.png (161.29 KiB) Viewed 401 times
"simply put, it's an old game"T — Cackfiend
User avatar
octalot
Developer
Posts: 521
Joined: July 17th, 2010, 7:40 pm
Location: Austria

Re: Questions about [event] name=time over

Post by octalot »

AFAICS it's all in data/multiplayer/eras.lua , and it's triggered by an [event]name="time over" in data/multiplayer/eras.cfg.

Looks as if you can disable it by setting (in WML) show_turns_over_advantage = no, and then use your own modified version of it instead. Awarding victory to one side can probably be done with an [endlevel]result=victory inside the time over event.
demario
Posts: 20
Joined: July 3rd, 2019, 1:05 pm

Re: Questions about [event] name=time over

Post by demario »

octalot wrote: September 24th, 2020, 11:02 am it's all in data/multiplayer/eras.lua , and it's triggered by an [event]name="time over" in data/multiplayer/eras.cfg.
Kudos octalot, things are very clear now: final score = income score + unit score + gold score
  • gold score = team's gold
  • income score = income * 5
  • unit score = math.max(type.cost * %hp, best_adv.cost * %xp)
I am wondering if this calculation could be more robust :hmm:

[income]
  • The income factor is somehow already present in the unit/gold score: more steady income means more units or more gold.
  • If you have a long history of better income but units do not reflect that, it means you got more losses and possibly not doing that well
  • An incentive for instantaneous village advantage on the last turn (20 points for each village flipped) seems heavily impacting result based on ToD of the last turn (which should be second night if turns is multiple of 6 for fairness, helping chaotic teams).
[unit]
  • I don't think using advancement cost to evaluate the unit score is wise. The cost of level 2 in known to be very roughly set. For example Elder Wose (31) is 11 gold more than 20 gold Wose while Elvish Captain and Ranger (32, 38) are 4 gold over the double of their corresponding level 1 (14, 17).
  • Elvish Captain and Ranger (32, 38) can also be compared to the value of Swordman (25) and Longbowman (26).
  • Next factor is the all-or-nothing choice between XP and HP. A 10%-HP, 90%-XP elvish archer (ie. 3 HP, 3XP to level) would be estimated to 35 gold while a full heath new archer is 17 gold. I would not spend 35 gold on a 3 HP archer.
Maybe something like type.cost * (%hp + %xp) or type.cost * (type.max_hp * %hp + best_adv.max_hp * %xp)/type.max_hp would be better. With best_adv.max_hp = type.max_hp if no advancement available.
  • That would leave the problem of already leveled units (but might not happen that much)
[leader]
Maybe adding a leader specific score: HP, access to keep, area for next move, ... maybe moving the income/gold factor here too :doh:
"simply put, it's an old game"T — Cackfiend
User avatar
Helmet
Posts: 200
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: Questions about [event] name=time over

Post by Helmet »

demario wrote: October 23rd, 2020, 8:47 amI don't think using advancement cost to evaluate the unit score is wise. The cost of level 2 in known to be very roughly set.
In my opinion, a lot of thought goes into the cost of level 2 units. I've noticed that in many updates to BfW, unit costs are scrutinized by the developers to make gameplay more balanced. Some costs go up as little as 1 gold, some costs go down as little as 1 gold. The developers evidently believe that the cost of a level 2 unit can create imbalances if the numbers are off.

For example, there are 15 adjustments to costs in the changelog for the recent release of 1.15.6, all done for the purpose of balancing.

If you want to avoid relying on level 2 unit costs in your formula, maybe you could assign each level 2 unit a value based on how valuable you think it is, and use that instead.

Or, within your formula, modify the cost of specific units that you think should be cheaper or costlier.
demario
Posts: 20
Joined: July 3rd, 2019, 1:05 pm

How to use [endlevel] in PvP multiplayer?

Post by demario »

octalot wrote: September 24th, 2020, 11:02 am Awarding victory to one side can probably be done with an [endlevel]result=victory inside the time over event.
Man, I am completely confused here. It is not working. The victory (or defeat) result is passed to both sides equally.
If I try to write both turn_limit_victory and turn_limit_defeat and call one for each side, it tells me that [endlevel] is used twice and discards it.
double_endlevel.png
double_endlevel.png (65.53 KiB) Viewed 247 times
How can I make one side wins and the other side loses?
octalot wrote: October 24th, 2020, 8:48 am The Creep War add-on's am_i_victorious function seems to be the most concise example (and the line that calls it is also relevant to this question).
There is no way I am going to understand this code, but it works. Much thanks for the pointer!
Last edited by demario on October 24th, 2020, 10:04 am, edited 1 time in total.
"simply put, it's an old game"T — Cackfiend
User avatar
octalot
Developer
Posts: 521
Joined: July 17th, 2010, 7:40 pm
Location: Austria

Re: Questions about [event] name=time over

Post by octalot »

Lua arrays use 1-based indices. So wesnoth.get_units { side = winning_sides[0] } is the same as wesnoth.get_units {}.

Your code should also check whether one of the winning sides is_local - and searching for code that uses that gives examples of how to do this. The Creep War add-on's am_i_victorious function seems to be the most concise example (and the line that calls it is also relevant to this question).
User avatar
GForce0
Posts: 48
Joined: May 17th, 2020, 5:58 pm

Re: How to use [endlevel] in PvP multiplayer?

Post by GForce0 »

EDIT: Actually I don't know if this will work inside time over event. I also had to do something similar and then I used it inside a turn end event of the last turn to work around it
demario wrote: October 24th, 2020, 7:18 am
Man, I am completely confused here. It is not working. The victory (or defeat) result is passed to both sides equally.
If I try to write both turn_limit_victory and turn_limit_defeat and call one for each side, it tells me that [endlevel] is used twice and discards it.
For different results for different sides you can use:

Code: Select all

[endlevel]
	result = victory
	reveal_map = no
	[result]
		result = defeat
		side = 1
	[/result]
	[result]
		result = defeat
		side = $unit.side
	[/result]
[/endlevel]
In this example all sides win, except side 1 and the side of a certain unit that triggered a certain event
You can adapt to your needs
demario
Posts: 20
Joined: July 3rd, 2019, 1:05 pm

What gold difference leads to sure defeat?

Post by demario »

Seems the code is running now with the modified am_i_victorious from Creep wars (from Vasya N, well done!).

I also want to improve the tie criteria so as to make a draw more an usual result when game stops at fixed number of turns.
The current code is checking equality of score, which make it unlikely and making some defeat very arbitrary (as the score computation is a rough guess).
I wondering which score difference should mark a clear advantage to decide victory. I see two ways to answer the question:
  • without taking the village grabbing into account, with how fewer gold at start than your equal strength opponent would you directly resign?
  • in an equal loyalist vs drake (or northerners vs rebels), with how many spearmen (or grunts) removed would you directly resign?
The answer to these questions can give an estimation of the difference of score (in gold) to trigger the defeat of one side (regardless how score in computed).

For now I will put 25 gold, but my feeling is that is still a bit low.
GForce0 wrote: October 24th, 2020, 12:15 pm EDIT: Actually I don't know if this will work inside time over event. I also had to do something similar and then I used it inside a turn end event of the last turn to work around it

Code: Select all

...
You can adapt to your needs
Much thanks for the support GForce0, this will help anyone playing with this in the future.
For the time being I will keep the Creep Wars version as it is sorted out in lua like the code I am struggling with.
"simply put, it's an old game"T — Cackfiend
demario
Posts: 20
Joined: July 3rd, 2019, 1:05 pm

How to value a wounded unit?

Post by demario »

demario wrote: October 23rd, 2020, 8:47 am [unit]
  • Next factor is the all-or-nothing choice between XP and HP.
Maybe something like type.cost * (%hp + %xp) or type.cost * (type.max_hp * %hp + best_adv.max_hp * %xp)/type.max_hp would be better.
Another problem with the formula is that a very low XP, from 1HP to less than type.max_hp/type.costHP unit accounts for 0 into the team score.
That would help teams with poison to outscore their opponent and goes against the evidence that people value such units enough to retreat/heal them.

A calculation such as type.cost * (type.max_hitpoints * (1.+2*%hp)/3 + best_adv.max_hitpoints * %xp)/type.max_hitpoints make sense, as it makes these units to score a third of their recruit value (between 4 to 8 gold generally speaking). Full health, 0XP unit still scores its recruit cost.
"simply put, it's an old game"T — Cackfiend
Post Reply