Skip to content

Comments

bugfix(particlesys): Delay creation of particle emitters until postProcess#2333

Open
stephanmeesters wants to merge 3 commits intoTheSuperHackers:mainfrom
stephanmeesters:bugfix-nonsavable-emitters-xfer
Open

bugfix(particlesys): Delay creation of particle emitters until postProcess#2333
stephanmeesters wants to merge 3 commits intoTheSuperHackers:mainfrom
stephanmeesters:bugfix-nonsavable-emitters-xfer

Conversation

@stephanmeesters
Copy link

@stephanmeesters stephanmeesters commented Feb 20, 2026

During loading a savegame, some particle systems were created before ParticleSystemManager had the opportunity to xfer-load the saved particle systems, which led to the possibility that some of these early created particle systems could be overwritten in m_systemMap of ParticleSystemManager. When that happens they would no longer reliably be able to use master/slave systems. The retail game does not use master/slave on the involved effects but it could appear as an issue with some mods (as the bug report describes too).

Misc findings

W3DTankDraw and W3DTankTruckDraw would create particle systems in the constructor, only to purge and recreate them again in postProcess, this has been changed to look if we're loading a savegame and then only create it once.

GrantStealthBehavior triggers when you do a GPS scrambler, but the behavior and associated particle effect will only last for one frame. The particle effect references a texture that's available in Generals but not in Zero Hour. So I think that so far nobody has been able to see this particle effect in action.

Todo

  • Replicate in Generals

@stephanmeesters stephanmeesters force-pushed the bugfix-nonsavable-emitters-xfer branch from 7418b31 to 16135b2 Compare February 22, 2026 19:54
@stephanmeesters stephanmeesters marked this pull request as ready for review February 22, 2026 20:43
@greptile-apps
Copy link

greptile-apps bot commented Feb 22, 2026

Greptile Summary

Fixes particle system corruption during savegame loading by deferring emitter creation until postProcess. Previously, particle systems created in constructors could be overwritten in ParticleSystemManager::m_systemMap before saved systems were loaded, breaking master/slave relationships in mods.

Key changes:

  • W3DTankDraw and W3DTankTruckDraw: Conditional emitter creation in constructor, removed redundant toss/recreate in postProcess
  • AutoHealBehavior and GrantStealthBehavior: Extracted emitter creation into new createEmitters() helper with double-creation guard
  • All changes check TheGameState->isInLoadGame() to defer creation during load
  • The new createEmitters() methods check m_radiusParticleSystemID == INVALID_PARTICLE_SYSTEM_ID before creating, addressing previous review feedback

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix addresses a well-understood race condition with a clean architectural solution. All emitter creation is now properly guarded against double-creation, and the deferred initialization pattern is consistently applied across all affected modules. The changes eliminate wasteful toss/recreate cycles and follow the existing codebase patterns (e.g., W3DTankDraw::createTreadEmitters already checks for INVALID_PARTICLE_SYSTEM_ID).
  • No files require special attention

Important Files Changed

Filename Overview
Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankDraw.cpp Delays tread emitter creation during savegame load, removes redundant toss/recreate in postProcess
Core/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DTankTruckDraw.cpp Delays tread emitter creation during savegame load, removes redundant toss/recreate in postProcess
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp Implements deferred particle system creation with double-creation guard in new createEmitters() method
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/GrantStealthBehavior.cpp Implements deferred particle system creation with double-creation guard in new createEmitters() method

Last reviewed commit: 8ada250

@stephanmeesters stephanmeesters force-pushed the bugfix-nonsavable-emitters-xfer branch from 16135b2 to 7b4b2fd Compare February 22, 2026 20:48
@stephanmeesters stephanmeesters changed the title bugfix(particlesys): Delay creation of non-savable particle emitters until postProcess bugfix(particlesys): Delay creation of particle emitters until postProcess Feb 22, 2026
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.

6 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
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.

6 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

…toHealBehavior.cpp

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
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.

W3DTankDraw::createEmitters create new particle system before XFER_LOAD of TheParticleSystemManager cause save crash..

1 participant