Skip to content

fix(spectregunship): Decouple gattling targeting logic from particle crc - #3055

Open
Okladnoj wants to merge 1 commit into
TheSuperHackers:mainfrom
Okladnoj:okji/fix/headless-particle-templates
Open

fix(spectregunship): Decouple gattling targeting logic from particle crc#3055
Okladnoj wants to merge 1 commit into
TheSuperHackers:mainfrom
Okladnoj:okji/fix/headless-particle-templates

Conversation

@Okladnoj

@Okladnoj Okladnoj commented Aug 3, 2026

Copy link
Copy Markdown

When the game logic was decoupled from the particle systems, SpectreGunshipUpdate was left coupled.

The gattling targeting logic only ran when the particle template was present. In headless mode (RETAIL_COMPATIBLE_CRC=0) the templates are not loaded, so the pointer is null and the block was skipped → the logic CRC of a headless client diverges from a graphical one.

Decoupled following the same pattern as the neighboring fixes (marker // TheSuperHackers @fix The particle system is now decoupled from the logic crc):

Retail is preserved under #if RETAIL_COMPATIBLE_CRC. Verified with a full deterministic replay (headless macOS ↔ Windows).

Comment thread Core/GameEngine/Include/GameClient/ParticleSys.h Outdated
Comment thread Core/GameEngine/Include/GameClient/ParticleSys.h Outdated
Comment thread Core/GameEngine/Include/GameClient/ParticleSys.h
@Okladnoj
Okladnoj force-pushed the okji/fix/headless-particle-templates branch from d656c3f to 23cbbf0 Compare August 5, 2026 00:53
@Okladnoj

Okladnoj commented Aug 5, 2026

Copy link
Copy Markdown
Author

@Caball009 Caball009 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The title and description are no longer up-to-date, and provide inadequate rationale for this change. It's not at all clear to me why this change would be needed.

@Okladnoj
Okladnoj force-pushed the okji/fix/headless-particle-templates branch from 23cbbf0 to 53458d0 Compare August 5, 2026 10:21
With RETAIL_COMPATIBLE_CRC=0 the headless dummy particle manager does not
load particle system templates, so data->m_gattlingStrafeFXParticleSystem
is null. The gattling targeting block was gated on that pointer, so a
headless client skipped it and left m_gattlingTargetPosition and
m_okToFireHowitzerCounter unchanged, diverging in logic crc from a
graphical client; the howitzer GameLogicRandomValue calls then cascade the
desync further.

Run the targeting logic whenever the gattling is firing in the non-retail
branch, independent of the template, and keep the template check only on
the client-side particle creation. The original condition is preserved
under RETAIL_COMPATIBLE_CRC so retail stays byte-identical even if an INI
omits the particle template. Matches the pattern used in EMPUpdate,
SpecialAbilityUpdate and TransitionDamageFX.
@Okladnoj
Okladnoj force-pushed the okji/fix/headless-particle-templates branch from 53458d0 to d9eaaeb Compare August 5, 2026 10:53
@Okladnoj Okladnoj changed the title fix(particlesys): Load particle system templates in headless mode without retail compatibility fix(spectregunship): Decouple gattling targeting logic from particle crc Aug 5, 2026
@Okladnoj

Okladnoj commented Aug 5, 2026

Copy link
Copy Markdown
Author

@xezon @githubawn
Fixed fix and discription

@Caball009 Caball009 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The current description and change make a lot more sense to me. I checked with RETAIL_COMPATIBLE_CRC disabled and there's indeed a mismatch issue here for headless mode.

I have added two suggested changes that'll provide a cleaner overall change.

PS: The game uses "gattling" all over the place, but the actual spelling is "gatling".

Comment on lines 618 to +624
const ParticleSystemTemplate *tmp = data->m_gattlingStrafeFXParticleSystem;
// TheSuperHackers @fix The particle system is now decoupled from the logic crc
#if RETAIL_COMPATIBLE_CRC
if (tmp && gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) )
#else
if (gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) )
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

#if RETAIL_COMPATIBLE_CRC
	// TheSuperHackers @fix The particle system is now decoupled from the logic crc
	const ParticleSystemTemplate *tmp = data->m_gattlingStrafeFXParticleSystem;
	if (tmp && gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON ))
#else
	if ( gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) )
#endif

Comment on lines +653 to +658
// TheSuperHackers @fix The particle system is now decoupled from the logic crc
#if RETAIL_COMPATIBLE_CRC
if ( gunship->getShroudedStatus( localPlayer->getPlayerIndex() ) <= OBJECTSHROUD_PARTIAL_CLEAR )
#else
if ( tmp && gunship->getShroudedStatus( localPlayer->getPlayerIndex() ) <= OBJECTSHROUD_PARTIAL_CLEAR )
#endif

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

It's cleaner if you don't change this code and change this instead on line 662:

ParticleSystem *sys = TheParticleSystemManager->createParticleSystem(data->m_gattlingStrafeFXParticleSystem);

createParticleSystem does a nullptr check on the ParticleSystemTemplate pointer.

@Caball009
Caball009 dismissed their stale review August 5, 2026 14:07

Changes since review.

@Caball009

Copy link
Copy Markdown

I wonder if there are more cases like this that we overlooked. The retail compatible changes were checked pretty thoroughly with a lot replays, but that's less easy to do for non-retail.

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.

4 participants