Live data from Hacker News

Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

reddit.com

21–30 of 267 posts

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#21
Rather than linking to this Reddit thread, wouldn't it make more sense to either link to:

* The linked-to patch notes? https://www.ageofempires.com/news/age-of-empires-ii-definiti...

* The particular comment explaining this bug fix? https://old.reddit.com/r/Games/comments/12jbb9d/age_of_empir...

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#22
post #14
post #3

This is a fantastic out of context change log. For even more abstract ones I cannot recommend enough the Dwarf Fortress Bugs Twitter account[0] The last of which is > Flying creatures keep exploding into pieces and dying: Are they crashing into trees? [0]sadly no Mastodon, https://twitter.com/DwarfFortBugs

Paradox Interactive games, especially the Crusader Kings series also have some pretty entertaining change logs. E.g., from Crusader Kings II, Patch 2.4 [0]: - Handsome and lustful men now also populate the cabins in the wild for the pleasures of people who find them attractive. - Characters who love their spouses very much are now less likely to join holy orders. - Paranoid parents should no longer worry about potent…

Wow, the logic to model these kinds of social structures makes my head hurt. But you would have to do it.

And I wonder about dead children. I remember one game where there could be no dead children.

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#24
post #8

ok, but who but TheViper or DauT has this issue? ಠ_ಠ (As a Japanese main, nerf Aztecs.)

Wow this comment had me reminiscing of watching AocZone tournaments replays of them in my youth Sigh

Always a little surreal to see the Viper still around. He used to be a legend in the forums 20 years back.

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#25

What’s the best way to play AoE on a MacBook? I can’t afford a dedicated game rig so any pointers would be of great help.

This is what I found for the M1 https://old.reddit.com/r/macgaming/comments/ms8081/age_of_em...

Seems to work fine with Wine and Crossover.

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#26

Fun fact: The competitive AoE2 scene remains very much alive and thriving. Several top players are able to make a living from it, thanks to streaming revenue and tournament prize money. There are even some streamers, such as T90 and MembTV, that have managed to create successful careers despite not being competitive players themselves.

Note that T90 is like 2300 Elo. Which isn't "top level pro", but I'm pretty sure he'd kick most of our asses.

T90 is probably the strongest dedicated commentator / announcer / caster in this community.

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#27

Earlier quoted context omitted.

> The formula was probably `return new_maxhp * (old_hp / old_maxhp);` ... > Due to floating point rounding errors, convert_hp(1, 55, 55) equals 0.999999940395355224609375, which is less than 1, which means the unit dies. Ahh. The old "Multiplying and dividing is associative... for the set of reals, not for the subset that you can actually afford to compute with." So it should have been `(new_maxhp * old_hp) / old_max…

Seems all that could have been avoided by using rationals in general and the condition for living being >0 instead of dying The more I write code, the more I notice how rarely one truly should want floats in most kinds of programs and how they almost always carry a whole bag of problems with them.

> Seems all that could have been avoided by using rationals in general

It's 2023: I'm still surprised that so many new languages/platforms still only provide only basic integer and IEEE-754 types for numerics: Rust, C#, Java, Swift and others still lack built-in, runtime-provided, nor even standard-library-provided rational types, which I assume really should be the preferred type for most business/domain/application values, exactly for things like RTS game unit health, for example. (and Java's lack of operator overloading makes this even more painful).

----

On a related note, can we agree that an application-programming language today should also include signed-and-unsigned "money-safe" decimal types, and IEEE-754 types should be smarter about when NaN can happen - and it should support interval types (and evaluating interval-type-based contract invariants): this would eliminate whole classes of bugs in the first place (too many programmers think single/double is appropriate for storing currency values, ugh).

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#28
post #2

From the comments: "This was caused by a floating point rounding error. A unit switching jobs internally becomes a different unit (i.e. a monk with a relic becomes a monk without a relic), and when doing that, HP is scaled proportionally based on the old and new max HP using 32-bit floating point maths." And there are YouTube videos about this https://www.youtube.com/watch?v=MytWNbpnAVY

> The formula was probably `return new_maxhp * (old_hp / old_maxhp);` ... > Due to floating point rounding errors, convert_hp(1, 55, 55) equals 0.999999940395355224609375, which is less than 1, which means the unit dies. Ahh. The old "Multiplying and dividing is associative... for the set of reals, not for the subset that you can actually afford to compute with." So it should have been `(new_maxhp * old_hp) / old_max…

Could you explain to a noob why does this happen, exactly?

Is it because 55/55 != 1, or 1*1 != 1?

I understand float can't store certain integer/finite decimal precisely, but why would a/a not be 1 if both numerator and denominator are the same (imprecise) number?

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#29

Earlier quoted context omitted.

> The formula was probably `return new_maxhp * (old_hp / old_maxhp);` ... > Due to floating point rounding errors, convert_hp(1, 55, 55) equals 0.999999940395355224609375, which is less than 1, which means the unit dies. Ahh. The old "Multiplying and dividing is associative... for the set of reals, not for the subset that you can actually afford to compute with." So it should have been `(new_maxhp * old_hp) / old_max…

Could you explain to a noob why does this happen, exactly? Is it because 55/55 != 1, or 1*1 != 1? I understand float can't store certain integer/finite decimal precisely, but why would a/a not be 1 if both numerator and denominator are the same (imprecise) number?

it's because the calculation (1/ 55) is less than the real number 1/55, so when you multiply it by 55 you get a result less than 1.

for an easier to follow example, say you can only work with two decimal places, hp was 1, old max hp was 3 and new max hp was also 3. if you do (3 * 1) / 3 you get 3 / 3 = 1 as intended. if instead you do 3 * (1 / 3) you get 3 * 0.33 = 0.99 which is less than 1

Re: Aztec monks with 1/55 HP no longer die when picking up or dropping a relic

#30

Earlier quoted context omitted.

> The formula was probably `return new_maxhp * (old_hp / old_maxhp);` ... > Due to floating point rounding errors, convert_hp(1, 55, 55) equals 0.999999940395355224609375, which is less than 1, which means the unit dies. Ahh. The old "Multiplying and dividing is associative... for the set of reals, not for the subset that you can actually afford to compute with." So it should have been `(new_maxhp * old_hp) / old_max…

Seems all that could have been avoided by using rationals in general and the condition for living being >0 instead of dying The more I write code, the more I notice how rarely one truly should want floats in most kinds of programs and how they almost always carry a whole bag of problems with them.

You mean fixed point numbers presumably, because at the time using integers that use a variable amount of memory was totally out of the question. Today it’s still terrible for performance because you can’t use caches and simd effectively when numbers can’t be packed directly in arrays.
Post reply on HN