Skip to content

tweak(network): Transfer assets of disconnected players to allies#1523

Merged
xezon merged 2 commits into
TheSuperHackers:mainfrom
Stubbjax:transfer-disconnected-player-assets
Sep 18, 2025
Merged

tweak(network): Transfer assets of disconnected players to allies#1523
xezon merged 2 commits into
TheSuperHackers:mainfrom
Stubbjax:transfer-disconnected-player-assets

Conversation

@Stubbjax

@Stubbjax Stubbjax commented Sep 2, 2025

Copy link
Copy Markdown

Fixes #162

This change allows a player's assets to be transferred to their allies upon disconnect.

@Stubbjax Stubbjax self-assigned this Sep 2, 2025
@Stubbjax Stubbjax added Enhancement Is new feature or request Major Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour labels Sep 2, 2025
@bobtista

bobtista commented Sep 2, 2025

Copy link
Copy Markdown

LGTM.
A nit for another PR would be to consider reusing the areAllies method vs checking the relationship in both directions here. It lives in victory conditions, but it's static inline there, so maybe moving it somewhere like GameCommon.h which already has the Relationship enum would make sense.
Another nit I might set a bool for foundAlly and add it to the loop conditions, instead of just using break. This is just a preference thing, keeping the diff smaller is good, and it's perfectly readable as is.

btw I love the code comments here, haven't heard the word bonehead in ages :)

Comment thread Generals/Code/GameEngine/Source/GameNetwork/Network.cpp Outdated
#if RETAIL_COMPATIBLE_CRC
msg->appendBooleanArgument(FALSE);
#else
msg->appendBooleanArgument(TRUE);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I do wonder, should transfer assets on disconnect be configurable in GameData.ini? Given EA designed it this way, maybe some Mods want to preserve the original design and encourage players to upkeep stable connections that way?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I can agree with that statement. I can see how some mods would like to have this behavior adjustable. It would be especially useful to know who would receive the assets in case there are multiple players on the team left, as possible with 3v3 or more. This goes for surrendering normally too.

For in the far future it would be interesting to make this setting adjustable further; do players get all assets, are they randomly distributed among remaining teammates, or do you get money only?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I cannot come up with reasonable rationale for making this adjustable or why a mod or even anyone would think this is desirable. What benefit is there to differentiating behaviour between surrender and disconnect? If a setting is desired for what happens to an ally's assets on defeat, it should apply to all cases and not differ between exit, surrender or disconnect.

Besides that, I don't think it's worth giving any weight to whether 'EA designed it this way,' considering we can see an unused alternative implementation in Network::RelayCommandsToCommandList with the assets being transferred. I doubt there's any intentional design here, especially when the alternative is an objective improvement.

@xezon xezon Sep 4, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I cannot come up with reasonable rationale for making this adjustable or why a mod or even anyone would think this is desirable.

There is a tangible difference between transfering assets on surrender and on disconnect: The first is a concious choice by the player. The second is likely an accident. Team mates and opponents can vote a player out. Historically team mates were not encouraged to vote out their team mate. But with this change, team mates could be encouraged to vote out their team mate (fast), for example if the player is not a good player and the team mates want to get hands on his stuff. I think this change will have some impact on user behavior in the disconnect screen.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Why should that difference have any bearing on gameplay? Whether it's a conscious choice or an accident, the outcome is the same and the player is no longer playing.

Following your logic, the opposite is currently true and players are encouraged to vote out their opponents (fast). Is this not worse? And does it even make a difference given that all players have to vote? I think you're overlooking the fact that a team's opponents would also have to vote out the respective player (fast), and I doubt they'd be so hasty to do so if it was disadvantageous.

I don't understand your example; if a player is deemed bad, their team mate(s) will often tell them to quit so they get their stuff or they'll simply restart with someone else. Do you think it's realistic for them to wait around on the off chance that particular player disconnects so that they (and their opponents, apparently) can vote them out (fast)?

Regardless, if the disconnect timer is going to reach 0 anyway - and it usually is when voting comes into effect - then voting outcomes / behaviour is irrelevant and only serves to expedite the process.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

@WWB2-account I still don't understand how this is any different. If coop must end in failure when one player is defeated, what currently happens if a player surrenders or quits (and thus transfers their assets to their ally)? Is the outcome not the same?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

In retail, defeated =/= surrender or quit., but defeated == disconnect. This change breaks that.

Defeated = when the essential assets to win the game no longer exist, e.g. when a player loses their Col. Burton in a infiltration-type coop mission or when their last building is destroyed in multiplayer.

Surrender or quit = when a player decides not to play anymore, for any reason. This is always a player choice. Their essential assets still exist at the moment of surrendering/quitting; if they don't exist, they cannot surrender and are defeated instead. Their assets are transferred to allies; if no allies remain (1v1), all assets are destroyed and they are effectively defeated.

Disconnect = the connection screws up because of a million reasons, and destroys all assets of disconnected player. Thus, they are effectively defeated. This forces players to either:

  • Retry the mission in case of coop;
  • Play with one fewer players in case of multiplayer

This is always involuntary, not a player choice.

=========================================================
Here's an overview of behaviors:

RETAIL BEHAVIOR

Multiplayer:
Defeated: all assets of a player are destroyed. They can no longer play and become observer or they exit. (GOOD)
Disconnect: connection screws up. Their assets are destroyed (!) and are kicked out of the game. (BAD)
Surrender/quit: they choose to stop playing, for any reason, and become observer or exit. Any assets they have transfer to allies. (GOOD)

Coop:
Defeated: all essential assets of a player are destroyed. They can no longer complete the mission. The mission ends in failure. (GOOD)
Disconnect: connection screws up. Their assets are destroyed (!) and the game ends in failure. (GOOD)
Surrender/quit: they choose to stop playing, for any reason. Any assets they have transfer to allies. (BAD)

THIS CHANGE

Multiplayer:
Defeated: all assets of a player are destroyed. They can no longer play and become observer or they exit. (GOOD)
Disconnect: connection screws up. Their assets are not destroyed (!) and are transferred to allies (this change), but they are still kicked out of the game. (GOOD)
Surrender/quit: they choose to stop playing, for any reason, and become observer or exit. Any assets they have transfer to allies. (GOOD)

Coop:
Defeated: all essential assets of a player are destroyed. They can no longer complete the mission. The mission ends in failure. (GOOD)
Disconnect: connection screws up. Their assets are not destroyed (!) and are transferred to allies (this change), but they are still kicked out of the game. (BAD)
Surrender/quit: they choose to stop playing, for any reason. Any assets they have transfer to allies. (BAD)

=========================================================
So for multiplayer, this change is most excellent. However, this has an unwanted side effect for coop missions. This is what Xezon and I are trying to say, and is why Xezon suggested:

How about add a "TransferPlayerAssetsOnDisconnect = yes/no" option to GameData.ini ?

I personally think that this shouldn't be a global on/off switch but a local one, in map.ini

=========================================================

I still don't understand how this is any different. If coop must end in failure when one player is defeated, what currently happens if a player surrenders or quits (and thus transfers their assets to their ally)? Is the outcome not the same?

Yes the outcome is the same with this change, but that outcome is bad for coop.

=========================================================
I think we can agree that comparing coop and multiplayer is like comparing apples and oranges. Coop missions are uncommon at best, while multiplayer games are played every day on all skill levels. Because this change has a benefit on multiplayer games, I think it can be merged. The problems it will cause are limited.

However, I expect there will be a follow-up that further addresses the issues (whether they were introduced by this change or not), so behavior becomes like this:

EXPECTED/FIXED BEHAVIOR

Multiplayer:
Defeated: all assets of a player are destroyed. They can no longer play and become observer or they exit. (GOOD)
Disconnect: connection screws up. Their assets are not destroyed (!) and are transferred to allies (this change), but they are still kicked out of the game. (GOOD)
Surrender/quit: they choose to stop playing, for any reason, and become observer or exit. Any assets they have transfer to allies. (GOOD)

Coop:
Defeated: all essential assets of a player are destroyed. They can no longer complete the mission. The mission ends in failure. (GOOD)
Disconnect: connection screws up. Their assets are destroyed (!) and the game ends in failure. (GOOD)
Surrender/quit: they choose to stop playing, for any reason. Any assets do not transfer to allies and the misson ends in failure. (GOOD)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Does map.ini accept GlobalData overrides?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm inclined to say it doesn't, but don't know for sure

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I understand and agree with the expected / fixed behaviour. However, if retail behaviour does not currently result in failure when an ally quits or surrenders, then the idea of coop is already easily defeated; which is a separate issue that should be addressed accordingly.

It is up to the map maker to control whether a player's defeat / surrender / quit / disconnect (collectively) results in failure and ends the game, and this is already doable with scripting as far as I know.

*** IF ***
  Player player0 currently owns  0  or fewer buildings.
*** OR ***
  Player player1 currently owns  0  or fewer buildings.
*** THEN ***
  Show 'Defeated' window and end game

Ideally there is a Player is defeated or Player is active script condition that does not depend on asset counts or everything having been destroyed, but that can be a future enhancement. Whether assets are transferred or not for coop games is irrelevant if the map's script appropriately fails the mission regardless.

Ultimately, I find it unnecessary to complicate this change with a setting that is expected to be (and effectively is already) superseded for the sole purpose of maintaining an implicit disconnect fail condition for improperly configured coop maps. We can look at adding a future setting to control whether assets are transferred when a player leaves a match.

This is always involuntary, not a player choice.

Always, you say?

image

@xezon xezon added the NoRetail This fix or change is not applicable with Retail game compatibility label Sep 18, 2025
@xezon xezon changed the title feat: Transfer assets of disconnected players to allies feat(network): Transfer assets of disconnected players to allies Sep 18, 2025
@xezon xezon changed the title feat(network): Transfer assets of disconnected players to allies tweak(network): Transfer assets of disconnected players to allies Sep 18, 2025
@xezon xezon merged commit 5765997 into TheSuperHackers:main Sep 18, 2025
19 checks passed
@Stubbjax Stubbjax deleted the transfer-disconnected-player-assets branch September 18, 2025 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement Is new feature or request Gen Relates to Generals Major Severity: Minor < Major < Critical < Blocker NoRetail This fix or change is not applicable with Retail game compatibility ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Team player base explodes on disconnect

4 participants