Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
fabian

demo-safe fix for "Baron attacks a monster behind him"?

Recommended Posts

Hi guys,

 

it has happened the second time within a few months that I have been asked to fix the "Baron attacks a monster behind him" issue in Crispy Doom.

 

https://doomwiki.org/wiki/Baron_attacks_a_monster_behind_him

 

The point is that if a Baron changes his target while he is in his S_BOS2_ATK2 state, then he will not turn his face to this new target, which makes it look like he is attacking his opponent from his back. A detailed analysis if this glitch has been provided by @RjY here

and a few lines later @entryway states that "It will affect sync only if attacked target is a spectre. Only in this case P_Random() is called."

 

Of course I honor this opinion, but I doubt that the only effect this has on demo sync is calling P_Random(). I can confirm, though, that not calling P_Random() if A_FaceTarget() is called from A_BruisAttack() leaves the few demos intact that I have tested so far (30plmax, 30pn4357, 30uv2325, 30uvmax4), but I cannot test them all and this might just be lucky incident.

 

But, what would happen if e.g. the Baron does a 180 turn due to this added code so that it cannot see the player (or a player in a multiplayer game) in P_LookForPlayers() anymore after finishing his target?

 

A patch for Crispy Doom (which will also work with Choco if you replace Crispy_SubRandom() with M_SubRandom()) can be found here and works surprisingly well:

https://github.com/fabiangreffrath/crispy-doom/pull/260#issuecomment-361091258

 

Any advice?

Share this post


Link to post

Have 2 different thing angle variables, one for game logic and one for rendering, and make A_BruisAttack only affect the latter one.

Share this post


Link to post
2 hours ago, fabian said:

But, what would happen if e.g. the Baron does a 180 turn due to this added code so that it cannot see the player (or a player in a multiplayer game) in P_LookForPlayers() anymore after finishing his target?

If the player hasn't shot in that sector and the Baron kills the enemy behind him, then the Baron would go back to sleep and totally mess up demo sync. Failing that, the fact that the Baron is now facing the other way will most likely change its next movement calculation (enemies will refuse to make a 180-degree turn while moving unless they have no other choice), which will also mess up sync. Seems to me that the only really "safe" way to do it is to make the Baron appear to face the new target, but it's only a visual change, and keep track of this separately from the Baron's actual state, somehow.

Share this post


Link to post

@scifista42 Yep, this is how I usually handle cases like this, but here it would be the whole work of duplicating the mobj->angle field just to mitigate this one rare issue. :/

 

@Linguica Thank you very much for confirming my doubts. This was pretty much the kind of thoughtful reply that I was hoping for!

Share this post


Link to post

Yes, a visual-only angle thingy would be the demo-safe way to go. But, the question becomes: When do you switch it back to normal? Do it too soon, and the baron "flickers". Do it too late, and the baron looks like he walks backwards!

Share this post


Link to post

Just make the monster have the "right" angle for the duration of the attack animation and then go back to normal. If that means the Baron appears to turn back around immediately after attacking then oh well.

Share this post


Link to post
1 hour ago, Linguica said:

Just make the monster have the "right" angle for the duration of the attack animation and then go back to normal. If that means the Baron appears to turn back around immediately after attacking then oh well.

That makes sense. I can't really say that it has ever really been noticeably distracting to me. Maybe because, if a baron is near, I'm high-tailing it to the nearest safe spot!

 

I guess a non-demo-safe mock-up would come close to demonstrating what the fix might look like. That, combined with a small handful of demos that would, at least, quickly get to a Baron encounter, before desyncing.

 

Honestly, I've always been fascinated to read up on discoveries like this. I think quirks like this add some mystique to Doom - a little bit of something that gets lost when it's fixed. Things like this add a tiny bit of personality to the Baron. "This guy can scratch behind his back!". I know it's not consistent. But, it's interesting. Most monsters have something unique, and quirky about them. It would be neat to compile a list of all the little, maybe unintended, differences. That so many of these differences were able to creep in demonstrates the vast depth of Doom.

 

Share this post


Link to post

Another solution could use a new thing flag. A_BruisAttack would merely set the flag on. The sprite rendering function would check this flag before rendering each sprite, and if the flag was set, the rendering function itself would calculate angle from the thing to its target and use this angle instead of the thing's actual angle. The only remaining problem is when to unset or invalidate the flag.

Share this post


Link to post

Suggestion: Fix it when it can't possibly break a demo

if (!(demoplayback || demorecording))
  A_FaceTarget(actor);

(I did similar in my source port years ago)

Share this post


Link to post
11 hours ago, RjY said:

Suggestion: Fix it when it can't possibly break a demo


if (!(demoplayback || demorecording))
  A_FaceTarget(actor);

 

I regularly used this approach in the past, but then decided I didn't want two different "feature sets" - or more generally "experiences" - when playing a regular game or recording/playing back a demo. Thus I always try to find ways to fix such little glitches that can be applied in all circumstances without risking demo or netgame sync.

Share this post


Link to post

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×