Skip to content

bugfix(behavior): Prevent fallen Angry Mob members from respawning at the Barracks after loading a save#2314

Merged
xezon merged 2 commits intoTheSuperHackers:mainfrom
Stubbjax:fix-unsaved-angry-mob-respawn-data
Feb 21, 2026
Merged

bugfix(behavior): Prevent fallen Angry Mob members from respawning at the Barracks after loading a save#2314
xezon merged 2 commits intoTheSuperHackers:mainfrom
Stubbjax:fix-unsaved-angry-mob-respawn-data

Conversation

@Stubbjax
Copy link

@Stubbjax Stubbjax commented Feb 16, 2026

Closes #11

This change fixes an issue where fallen Angry Mob members respawn at the Barracks after loading a save.

Angry Mob members spawn from the Barracks if m_initialBurstCountdown is greater than 0. As m_initialBurstCountdown is not saved in the retail game, it is always reset to its default/retail value of 5 when loading a saved game. This results in up to 5 Angry Mob members respawning from the Barracks and attempting to run across the map to join the nexus, where they often die again in the process due to being too far away.

Before

Fallen Angry Mob members respawn at the Barracks

BAD_SPAWN.mp4

After

Fallen Angry Mob members respawn at the nexus

GOOD_SPAWN.mp4

@Stubbjax Stubbjax self-assigned this Feb 16, 2026
@Stubbjax Stubbjax added Bug Something is not working right, typically is user facing GLA Affects GLA faction Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour NoRetail This fix or change is not applicable with Retail game compatibility labels Feb 16, 2026
@greptile-apps
Copy link

greptile-apps bot commented Feb 16, 2026

Greptile Summary

This PR fixes a bug where fallen Angry Mob members respawn at the Barracks instead of at the nexus after loading a save game. The root cause was that m_initialBurstCountdown was not serialized, so it reset to its default value (from SpawnBehaviorModuleData::m_initialBurst) on load, causing up to 5 mob members to re-exit from the Barracks.

  • Bumps the SpawnBehavior::xfer save format from version 2 to version 3, adding serialization of m_initialBurstCountdown
  • Uses the established RETAIL_COMPATIBLE_XFER_SAVE preprocessor guard to maintain backward compatibility with retail save files (version stays at 2 when enabled)
  • Identical changes applied to both Generals/ and GeneralsMD/ codebases
  • Follows existing codebase patterns for versioned xfer serialization exactly

Confidence Score: 5/5

  • This PR is safe to merge - it's a minimal, well-scoped bugfix that follows established patterns exactly.
  • The change is small and surgical: it adds serialization of a single field (m_initialBurstCountdown) to the save format, using the exact same versioned xfer pattern used throughout the codebase. The RETAIL_COMPATIBLE_XFER_SAVE guard ensures backward compatibility with retail saves. The xferUnsignedInt call matches the field's UnsignedInt type, consistent with how m_selfTaskingSpawnCount (same type) is serialized in the same function. Both Generals/ and GeneralsMD/ versions are updated identically.
  • No files require special attention.

Important Files Changed

Filename Overview
Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SpawnBehavior.cpp Adds version 3 xfer serialization for m_initialBurstCountdown with RETAIL_COMPATIBLE_XFER_SAVE guard, following established codebase patterns exactly.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/SpawnBehavior.cpp Mirror of the Generals/ change for Zero Hour - adds version 3 xfer serialization for m_initialBurstCountdown with RETAIL_COMPATIBLE_XFER_SAVE guard.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Load Save Game] --> B{Check xfer version}
    B -->|version >= 2| C[Deserialize m_initialBurstTimesInited]
    B -->|version < 2| D[Skip m_initialBurstTimesInited]
    C --> E{version >= 3?}
    D --> E
    E -->|Yes - New save format| F[Deserialize m_initialBurstCountdown\nfrom save data]
    E -->|No - Old save or retail| G[m_initialBurstCountdown keeps\nconstructor default value]
    F --> H[Countdown reflects actual\ngame state at save time]
    G --> I[Countdown resets to m_initialBurst\ne.g. 5 for Angry Mob]
    H --> J[Mob members respawn\nat nexus correctly]
    I --> K[Mob members respawn\nat Barracks - BUG]
Loading

Last reviewed commit: f350626

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

2 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Comment on lines +1011 to +1012
if (version >= 3)
xfer->xferUnsignedInt(&m_initialBurstCountdown);
Copy link

Choose a reason for hiding this comment

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

Inconsistent brace style with surrounding code (line 1007-1009 uses braces)

Suggested change
if (version >= 3)
xfer->xferUnsignedInt(&m_initialBurstCountdown);
if (version >= 3) {
xfer->xferUnsignedInt(&m_initialBurstCountdown);
}

Context Used: Rule from dashboard - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SpawnBehavior.cpp
Line: 1011:1012

Comment:
Inconsistent brace style with surrounding code (line 1007-1009 uses braces)

```suggestion
	if (version >= 3) {
		xfer->xferUnsignedInt(&m_initialBurstCountdown);
	}
```

**Context Used:** Rule from `dashboard` - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... ([source](https://app.greptile.com/review/custom-context?memory=16b9b669-b823-49be-ba5b-2bd30ff3ba6d))

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

Copy link

Choose a reason for hiding this comment

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

Prefer adding curly brace

Comment on lines +1096 to +1097
if (version >= 3)
xfer->xferUnsignedInt(&m_initialBurstCountdown);
Copy link

Choose a reason for hiding this comment

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

Inconsistent brace style with surrounding code (line 1092-1094 uses braces)

Suggested change
if (version >= 3)
xfer->xferUnsignedInt(&m_initialBurstCountdown);
if (version >= 3) {
xfer->xferUnsignedInt(&m_initialBurstCountdown);
}

Context Used: Rule from dashboard - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/SpawnBehavior.cpp
Line: 1096:1097

Comment:
Inconsistent brace style with surrounding code (line 1092-1094 uses braces)

```suggestion
	if (version >= 3) {
		xfer->xferUnsignedInt(&m_initialBurstCountdown);
	}
```

**Context Used:** Rule from `dashboard` - Always place if/else/for/while statement bodies on separate lines from the condition to allow precis... ([source](https://app.greptile.com/review/custom-context?memory=16b9b669-b823-49be-ba5b-2bd30ff3ba6d))

<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>

How can I resolve this? If you propose a fix, please make it concise.

@Skyaero42
Copy link

Question: Are they supposed to respawn at all?

@Stubbjax
Copy link
Author

Question: Are they supposed to respawn at all?

Yes; see SpawnReplaceDelay and ExitDelay fields in the data. See m_spawnReplaceDelayData and m_replacementTimes in the logic.

@Stubbjax Stubbjax added the Saveload Is Saveload/Xfer related label Feb 17, 2026
Copy link

@xezon xezon left a comment

Choose a reason for hiding this comment

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

Looks technically correct. Code style can be improved.

@xezon xezon changed the title bugfix: Prevent fallen Angry Mob members respawning at the Barracks after loading a save bugfix(behavior): Prevent fallen Angry Mob members respawning at the Barracks after loading a save Feb 21, 2026
@xezon xezon changed the title bugfix(behavior): Prevent fallen Angry Mob members respawning at the Barracks after loading a save bugfix(behavior): Prevent fallen Angry Mob members from respawning at the Barracks after loading a save Feb 21, 2026
@xezon xezon merged commit 0b8af6d into TheSuperHackers:main Feb 21, 2026
45 of 47 checks passed
@Stubbjax Stubbjax deleted the fix-unsaved-angry-mob-respawn-data branch February 22, 2026 00:05
CookieLandProjects pushed a commit to CookieLandProjects/CLP_AI that referenced this pull request Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals GLA Affects GLA faction Minor Severity: Minor < Major < Critical < Blocker NoRetail This fix or change is not applicable with Retail game compatibility Saveload Is Saveload/Xfer related ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In a skirmish game loaded from save, missing Angry Mob members respawn from production buildings instead of the Mob Nexus

3 participants