Skip to content

Decrement turns of unhappiness counter per city, if positive - #1008

Merged
ajhalme merged 3 commits into
C7-Game:Developmentfrom
zack-the-coding-actuary:SlavingUnhappinessBugfix
Sep 28, 2026
Merged

ajhalme merged 3 commits into
C7-Game:Developmentfrom
zack-the-coding-actuary:SlavingUnhappinessBugfix

Conversation

@zack-the-coding-actuary

Copy link
Copy Markdown
Contributor

Response to @Billytifft's bug report of unhappiness due to forced labor never decrementing.

#1004 (comment)

Quick fix potentially abusing short-circuiting logic, heh. I did some homework to make sure I understood how the mechanic worked (it's already good to go as-is), I'm still learning new things about this game!

Comment thread C7Engine/C7GameData/City.cs Outdated
// multiple citizens lost causes multiple unhappy faces.
if (turnsOfUnhappinessDueToPopRushing > 0) {
// Only decrement if greater than 0, only add unhappiness if greater than 0 after decrement
if (turnsOfUnhappinessDueToPopRushing > 0 && --turnsOfUnhappinessDueToPopRushing > 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to update the state here. RecalculateCitizenMoods should only do what it says on the tin.

I'd look into extending HandleCityUpdates(..) in class Player, or perhaps going up a level and doing a new segment in the per-player section of AdvanceTurn in TurnHandling.cs.

On a more stylistic note: I find that doing comparisons and variable updates on the same line of source code makes the overall logic harder to parse and understand at a glance.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes I see this needs to be a bit more surgical. RecalculateCitizenMoods can be called from multiple function paths here so we definitely don't want to decrement on every call. Okay, I'll think about how to organize this more cleanly and propose a different fix!

@zack-the-coding-actuary

Copy link
Copy Markdown
Contributor Author

I think something like this might be the cleanest solution. Updating the unhappiness penalty decrements in player.HandleCityUpdates means we have to account for the potential single extra turn of unhappiness in player.RecalculateCitizenMoods, which you actually don't know exists or not depending on where you're calling player.RecalculateCitizenMoods from. It can happen either during the interturn like in this turn advance step, OR in several other places.

So I think the most tractable solution is to have a small helper also in the Player class that fires exactly one time during AdvanceTurn and decrement everything there. Then all future calls to player.RecalculateCitizenMoods are valid without changing anything else in the method, which I think makes intent clearest and invasiveness minimal.

Happy to entertain any perspectives different than mine.

@ajhalme ajhalme left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one-liner is perhaps needlessly clever relative to the explicit

if (c.turnsOfUnhappinessDueToPopRushing > 0) {
    c.turnsOfUnhappinessDueToPopRushing -= 1;
}

but let us move on to greater things.

Thanks for the contribution!

@ajhalme
ajhalme merged commit 6b9100d into C7-Game:Development Sep 28, 2026
3 checks passed
@zack-the-coding-actuary

Copy link
Copy Markdown
Contributor Author

The one-liner is perhaps needlessly clever relative to the explicit

if (c.turnsOfUnhappinessDueToPopRushing > 0) {
    c.turnsOfUnhappinessDueToPopRushing -= 1;
}

but let us move on to greater things.

Thanks for the contribution!

But a ternary conditional move saves DOZENS of cycles compared to a branch misprediction!!

cough cough sorry, that was the C / C++ Green Goblin side of me..

@ajhalme

ajhalme commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

Well...

https://godbolt.org/z/qbPxErKbb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants