Have luck affect XP gained

Brainstorm ideas of possible additions to the game. Read this before posting!

Moderators: Forum Moderators, Developers

Forum rules
Before posting a new idea, you must read the following:
Post Reply
ErSidward
Posts: 3
Joined: March 12th, 2011, 3:37 am

Have luck affect XP gained

Post by ErSidward »

I've read a fair few rants about the RNG (and at times aren't too fond of it myself... though at others I love it), but I understand why it's here to stay. Yet I feel it's still a bit unfair at times, so I thought of a small "balancing" tweak that might help alleviate the inevitable localised strokes of luck and streaks of misfortune without interfering with the randomness: have damage dealt/received affect the experience gained, so that getting unlucky will net you more xp than normal. For example, we could have

final_xp = base_xp + floor[target_level * expected_damage_dealt/actual_damage_dealt]

or possibly
final_xp = base_xp + floor[target_level * (expected_damage_dealt/actual_damage_dealt + actual_damage_received/expected_damage_received) / 2]
which also takes into account damage received.

base_xp is the normal xp gained under the current system, and target_level could be replaced with 0.5 for level 0 units. I thought of a few different formulae, but I think this is nice and easy... it won't penalise you for getting lucky, so you won't be caught in a situation where you, say, have a low-hp spearman within 1xp of levelling up hit an adept, then fail to level simply because you scored 100% of the hits (without getting the kill), thus leaving the enemy with a live adept and your spearman next to dead against odds. It also won't screw around with kills too much (killing a unit against all odds won't yield a ridiculously large xp gain, and getting lucky at a high-level unit won't mean you get diddly squat).

User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Have luck affect XP gained

Post by 8680 »

You could try something like this:

Code: Select all

## I use Lua here because getting a unit’s current defense is considerably trickier in ActionWML.

[event]
    name=attack
    first_time_only=no
    [lua]
        code="damage1, damage2 = 0, 0"
    [/lua]
[/event]

[event]
    name=attacker_hits
    first_time_only=no
    [lua]
        code="damage1 = damage1 + wesnoth.get_variable('damage_inflicted')"
    [/lua]
[/event]

[event]
    name=defender_hits
    first_time_only=no
    [lua]
        code="damage2 = damage2 + wesnoth.get_variable('damage_inflicted')"
    [/lua]
[/event]

[event]
    name=attack_end
    first_time_only=no
    [lua]
        code=<<
            local function compute_average_damage(attack, target, target_is_primary_unit)
                -- This does not take into account weapon specials.
                -- wesnoth.simulate_combat could be used for greater accuracy, at a possible cost to speed.
                return attack.damage * attack.number
                    * wesnoth.unit_resistance(target, attack.type, target_is_primary_unit, target.x, target.y)
                    * wesnoth.unit_defense(target, wesnoth.get_terrain(target.x, target.y))
            end
            local event = wesnoth.current.event_context
            local unit1 = wesnoth.get_unit(event.x1, event.y1)
            local unit2 = wesnoth.get_unit(event.x2, event.y2)
            local avg_damage1 = compute_average_damage(event.weapon, unit2, false)
            local avg_damage2 = compute_average_damage(event.second_weapon, unit1, true)
            -- Implements the second formula.
            unit1.experience = unit1.experience + math.floor(wesnoth.get_variable("second_unit.level")
                *  (avg_damage1/damage1 + damage2/avg_damage2) * .5)
            unit2.experience = unit2.experience + math.floor(wesnoth.get_variable("unit.level")
                *  (avg_damage2/damage2 + damage1/avg_damage1) * .5)
            damage1, damage2 = nil, nil
        >>
    [/lua]
[/event]
It is of course highly doubtful that such a tweak would ever be accepted into mainline, but feel free to experiment with it yourself.

User avatar
Limabean
Posts: 350
Joined: August 26th, 2008, 2:14 pm
Location: New Hampshire, USA

Re: Have luck affect XP gained

Post by Limabean »

It is certainly an interesting idea (especially because as far as I know no one has suggested it before). With the current system, if xp is on the edge of a levelup, a very brief stretch of bad or good luck can have far more significant consequences than it would otherwise. I can imagine that this tweak might well alleviate that.

The main drawback that I see is that it is anti-KISS. Instead of just 2 possible xp outcomes from an attack, (kill xp or attack xp) you have a whole range of possible xp outcomes. It makes it difficult to plan your xp out ahead of time.

Still, I would definitely give this a try. I'm curious to see how balanced it is.
When a scientist states that something is possible, he is almost certainly right. When he states that something is impossible, he is very probably wrong.
-Arthur C. Clarke-

User avatar
A Guy
Posts: 790
Joined: May 24th, 2008, 1:55 am

Re: Have luck affect XP gained

Post by A Guy »

8680 wrote:You could try something like this:

Code: Select all

## I use Lua here because getting a unit’s current defense is considerably trickier in ActionWML.

[event]
    name=attack
    first_time_only=no
    [lua]
        code="damage1, damage2 = 0, 0"
    [/lua]
[/event]

[event]
    name=attacker_hits
    first_time_only=no
    [lua]
        code="damage1 = damage1 + wesnoth.get_variable('damage_inflicted')"
    [/lua]
[/event]

[event]
    name=defender_hits
    first_time_only=no
    [lua]
        code="damage2 = damage2 + wesnoth.get_variable('damage_inflicted')"
    [/lua]
[/event]

[event]
    name=attack_end
    first_time_only=no
    [lua]
        code=<<
            local function compute_average_damage(attack, target, target_is_primary_unit)
                -- This does not take into account weapon specials.
                -- wesnoth.simulate_combat could be used for greater accuracy, at a possible cost to speed.
                return attack.damage * attack.number
                    * wesnoth.unit_resistance(target, attack.type, target_is_primary_unit, target.x, target.y)
                    * wesnoth.unit_defense(target, wesnoth.get_terrain(target.x, target.y))
            end
            local event = wesnoth.current.event_context
            local unit1 = wesnoth.get_unit(event.x1, event.y1)
            local unit2 = wesnoth.get_unit(event.x2, event.y2)
            local avg_damage1 = compute_average_damage(event.weapon, unit2, false)
            local avg_damage2 = compute_average_damage(event.second_weapon, unit1, true)
            -- Implements the second formula.
            unit1.experience = unit1.experience + math.floor(wesnoth.get_variable("second_unit.level")
                *  (avg_damage1/damage1 + damage2/avg_damage2) * .5)
            unit2.experience = unit2.experience + math.floor(wesnoth.get_variable("unit.level")
                *  (avg_damage2/damage2 + damage1/avg_damage1) * .5)
            damage1, damage2 = nil, nil
        >>
    [/lua]
[/event]
It is of course highly doubtful that such a tweak would ever be accepted into mainline, but feel free to experiment with it yourself.
I'm a bit confused as to what your code does, may you please explain to me?
I'm just... a guy...
I'm back for now, I might get started on some work again.

User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: Have luck affect XP gained

Post by 8680 »

A Guy wrote:I'm a bit confused as to what your code does, may you please explain to me?
When combat begins, the Lua variables damage1 and damage2 are set to 0. These variables are used to track how much damage each unit dealt to its opponent: when the primary unit hits, the damage inflicted is added to damage1; when the secondary unit hits, the damage inflicted is added to damage2.

When the combat ends, the (approximate) average total damage that each unit could have been expected to inflict over the course of the combat is computed, then floor([i]opponent’s level[/i] × ([i]expected average damage inflicted[/i] ÷ [i]actual damage inflicted[/i] + [i]actual damage taken[/i] ÷ [i]expected average damage taken[/i]) ÷ 2) is computed for the primary unit, and the result added to its experience, then again for the secondary unit. The damage1 and damage2 variables are then cleared.

User avatar
A Guy
Posts: 790
Joined: May 24th, 2008, 1:55 am

Re: Have luck affect XP gained

Post by A Guy »

Oh, interesting. Thank you!
I'm just... a guy...
I'm back for now, I might get started on some work again.

Post Reply